package com.eastfair.home.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.eastfair.boot.request.PageParams;
import com.eastfair.builder.ExhibitorFeign;
import com.eastfair.builder.dto.ExhibitorDTO;
import com.eastfair.builder.entity.Exhibitor;
import com.eastfair.builder.enumeration.ExhibitorProcessEnum;
import com.eastfair.builder.enumeration.ExhibitorSiteTypeEnum;
import com.eastfair.builder.vo.ExhibitorVO;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.home.dao.SupervisionItemQuestionMapper;
import com.eastfair.home.entity.SupervisionItemManagement;
import com.eastfair.home.entity.SupervisionItemQuestion;
import com.eastfair.home.entity.VenueReportDrawingHistory;
import com.eastfair.home.enumeration.BoothAcceptanceRecordAcceptanceTypeEnum;
import com.eastfair.home.enumeration.SupervisionItemManagementSupervisionItemEnum;
import com.eastfair.home.enumeration.SupervisionItemQuestionQuestionTypeEnum;
import com.eastfair.home.service.BoothAcceptanceRecordService;
import com.eastfair.home.service.HomeServiceProviderSpaceService;
import com.eastfair.home.service.SupervisionItemManagementService;
import com.eastfair.home.service.SupervisionItemQuestionService;
import com.eastfair.boot.service.SuperServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;

import java.time.LocalDateTime;
import java.util.Collection;

//import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.aop.framework.AopContext;
import com.eastfair.annotation.annotation.cache.Magic;
import com.eastfair.annotation.annotation.cache.Cache;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
//import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import com.eastfair.home.vo.*;
import com.eastfair.home.dto.*;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * <p>
 * 业务实现类
 * 监督项管理问卷
 * </p>
 *
 * @author linan
 * @date 2022-11-29
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class SupervisionItemQuestionServiceImpl extends SuperServiceImpl<SupervisionItemQuestionMapper, SupervisionItemQuestion> implements SupervisionItemQuestionService {

    @Resource
    private SupervisionItemManagementService supervisionItemManagementService;

    @Resource
    private HomeServiceProviderSpaceService homeServiceProviderSpaceService;

    @Resource
    private BoothAcceptanceRecordService boothAcceptanceRecordService;

    @Resource
    private ExhibitorFeign exhibitorFeign;


    @Override
    protected R<Boolean> handlerSave(SupervisionItemQuestion model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        return R.successDef();
    }

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<SupervisionItemQuestion> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    /**
     * 通用查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    public List<SupervisionItemQuestion> list(SupervisionItemQuestionDTO modelDTO, List<Long> ids) {
        return ((SupervisionItemQuestionService) AopContext.currentProxy()).listOfCache(modelDTO, ids);
    }


    /**
     * 缓存查询
     *
     * @param modelDTO DTO
     * @param ids      主键id集合
     * @return list
     */
    @Override
    @Cache(key = "",
            magic = @Magic(
                    key = "{" +
                            "{'isEnabled', #args[0]?.isEnabled}," +
                            "{'supervisionItemManagementId', #args[0]?.supervisionItemManagementId}," +
                            "{'sort', #args[0]?.sort}," +
                            "{'title', #args[0]?.title}," +
                            "{'questionType', #args[0]?.questionType}," +
                            "{'minWordage', #args[0]?.minWordage}," +
                            "{'maxWordage', #args[0]?.maxWordage}," +
                            "{'textBoxType', #args[0]?.textBoxType}," +
                            "{'optionOne', #args[0]?.optionOne}," +
                            "{'optionOneFill', #args[0]?.optionOneFill}," +
                            "{'optionTwo', #args[0]?.optionTwo}," +
                            "{'optionTwoFill', #args[0]?.optionTwoFill}," +
                            "{'optionThree', #args[0]?.optionThree}," +
                            "{'optionThreeFill', #args[0]?.optionThreeFill}," +
                            "{'optionFour', #args[0]?.optionFour}," +
                            "{'optionFourFill', #args[0]?.optionFourFill}," +
                            "{'optionFive', #args[0]?.optionFive}," +
                            "{'optionFiveFill', #args[0]?.optionFiveFill}," +
                            "{'id', #args[1]}" +
                            "}"))
    public List<SupervisionItemQuestion> listOfCache(SupervisionItemQuestionDTO modelDTO, List<Long> ids) {
        //查询
        QueryWrapper<SupervisionItemQuestion> queryWrapper = new QueryWrapper<>();
        if (modelDTO != null) {
            queryWrapper.lambda().eq(modelDTO.getSupervisionItemManagementId() != null, SupervisionItemQuestion::getSupervisionItemManagementId, modelDTO.getSupervisionItemManagementId());
            queryWrapper.lambda().eq(modelDTO.getSort() != null, SupervisionItemQuestion::getSort, modelDTO.getSort());
            queryWrapper.lambda().eq(Objects.nonNull(modelDTO.getTitle()), SupervisionItemQuestion::getTitle, modelDTO.getTitle());
            queryWrapper.lambda().eq(Objects.nonNull(modelDTO.getQuestionType()), SupervisionItemQuestion::getQuestionType, modelDTO.getQuestionType());
            queryWrapper.lambda().eq(modelDTO.getMinWordage() != null, SupervisionItemQuestion::getMinWordage, modelDTO.getMinWordage());
            queryWrapper.lambda().eq(modelDTO.getMaxWordage() != null, SupervisionItemQuestion::getMaxWordage, modelDTO.getMaxWordage());
            queryWrapper.lambda().eq(Objects.nonNull(modelDTO.getTextBoxType()), SupervisionItemQuestion::getTextBoxType, modelDTO.getTextBoxType());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getOptionOne()), SupervisionItemQuestion::getOptionOne, modelDTO.getOptionOne());
            queryWrapper.lambda().eq(modelDTO.getOptionOneFill() != null, SupervisionItemQuestion::getOptionOneFill, modelDTO.getOptionOneFill());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getOptionTwo()), SupervisionItemQuestion::getOptionTwo, modelDTO.getOptionTwo());
            queryWrapper.lambda().eq(modelDTO.getOptionTwoFill() != null, SupervisionItemQuestion::getOptionTwoFill, modelDTO.getOptionTwoFill());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getOptionThree()), SupervisionItemQuestion::getOptionThree, modelDTO.getOptionThree());
            queryWrapper.lambda().eq(modelDTO.getOptionThreeFill() != null, SupervisionItemQuestion::getOptionThreeFill, modelDTO.getOptionThreeFill());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getOptionFour()), SupervisionItemQuestion::getOptionFour, modelDTO.getOptionFour());
            queryWrapper.lambda().eq(modelDTO.getOptionFourFill() != null, SupervisionItemQuestion::getOptionFourFill, modelDTO.getOptionFourFill());
            queryWrapper.lambda().eq(StringUtils.isNotBlank(modelDTO.getOptionFive()), SupervisionItemQuestion::getOptionFive, modelDTO.getOptionFive());
            queryWrapper.lambda().eq(modelDTO.getOptionFiveFill() != null, SupervisionItemQuestion::getOptionFiveFill, modelDTO.getOptionFiveFill());
        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(SupervisionItemQuestion::getId, ids);
        }
        queryWrapper.lambda().eq(SupervisionItemQuestion::getIsDeleted, BusinessConstant.DELETE_NO);
        List<SupervisionItemQuestion> modelList = list(queryWrapper);
        return modelList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveSupervisionItemQuestion(SupervisionItemManagementDTO dto) {
        Long id = dto.getId();
        // 作废旧的问卷
        update(new UpdateWrapper<SupervisionItemQuestion>().lambda()
                .eq(SupervisionItemQuestion::getIsDeleted,BusinessConstant.NO)
                .eq(SupervisionItemQuestion::getSupervisionItemManagementId,id)
                .set(SupervisionItemQuestion::getIsDeleted,BusinessConstant.YES));
        // 回滚展位验收状态
        rollbackSiteProcess(id);
        // 插入新的问卷
        if(CollectionUtils.isNotEmpty(dto.getSupervisionItemQuestionList())){
            for (SupervisionItemQuestionDTO supervisionItemQuestionDTO : dto.getSupervisionItemQuestionList()) {
                supervisionItemQuestionDTO.setSupervisionItemManagementId(id);
                save(BeanUtil.copyProperties(supervisionItemQuestionDTO,SupervisionItemQuestion.class));
            }
            // 更新监督项管理
            supervisionItemManagementService.updateById(SupervisionItemManagement.builder()
                    .id(id)
                    .questionNum(dto.getSupervisionItemQuestionList().size())
                    .updatedName(dto.getUpdatedName()).build());
        }else {
            // 更新监督项管理
            supervisionItemManagementService.updateById(SupervisionItemManagement.builder()
                    .id(id)
                    .questionNum(0)
                    .updatedName(dto.getUpdatedName()).build());
        }
        return true;
    }

    /**
     * 回滚展位进度
     * @param id
     */
    private void rollbackSiteProcess(Long id) {
        SupervisionItemManagement supervisionItemManagement = supervisionItemManagementService.getById(id);
        SupervisionItemManagementSupervisionItemEnum supervisionItem = supervisionItemManagement.getSupervisionItem();
        Long exhibitionManageId = supervisionItemManagement.getExhibitionManageId();
        PageParams<ExhibitorDTO> pageParams= new PageParams<>();
        pageParams.setSize(999999);
        pageParams.setCurrent(1);
        ExhibitorDTO serviceProviderSpaceQuery = new ExhibitorDTO();
        serviceProviderSpaceQuery.setExhibitionManageId(exhibitionManageId);
        pageParams.setModel(serviceProviderSpaceQuery);
        // 从搭建商查询展位信息
        R<Page<ExhibitorVO>> pageR = homeServiceProviderSpaceService.queryServiceProviderSite(pageParams);
        if(!pageR.getIsSuccess()){
            throw BizException.wrap(pageR.getCode(), pageR.getMsg());
        }
        List<ExhibitorVO> records = pageR.getData().getRecords();
        records = ConvertUtil.convertList(records,ExhibitorVO.class);
        for (ExhibitorVO record : records) {
            ExhibitorProcessEnum process = record.getProcess();
            if (supervisionItem.eq(SupervisionItemManagementSupervisionItemEnum.ARRANGEMENT)) {
                // 如果流程不是空、且流程不是"缴纳保证金"，则直接回滚到"缴纳保证金"
                if (Objects.nonNull(process) && !process.eq(ExhibitorProcessEnum.IS_EARNEST_MONEY_SET)) {
                    ExhibitorDTO updateEntity =new ExhibitorDTO();
                    updateEntity.setId(record.getId());
                    updateEntity.setProcess(ExhibitorProcessEnum.IS_EARNEST_MONEY_SET);
                    exhibitorFeign.updateExhibitor(updateEntity);
                }
                // 作废展位所有验收记录
                boothAcceptanceRecordService.removeByExhibitionManage(supervisionItemManagement,null);
            } else {
                // 如果流程是"撤展验收中"，则直接回滚到"布展验收"
                if (Objects.nonNull(process) && (process.eq(ExhibitorProcessEnum.DISMANTLING) || process.eq(ExhibitorProcessEnum.HAS_DISMANTLING))) {
                    ExhibitorDTO updateEntity =new ExhibitorDTO();
                    updateEntity.setId(record.getId());
                    updateEntity.setProcess(ExhibitorProcessEnum.HAS_ARRANGEMENT);
                    exhibitorFeign.updateExhibitor(updateEntity);
                }
                // 作废展位撤展验收记录
                boothAcceptanceRecordService.removeByExhibitionManage(supervisionItemManagement, BoothAcceptanceRecordAcceptanceTypeEnum.DISMANTLING.getCode());
            }
        }
    }

    @Override
    public List<SupervisionItemQuestionVO> querySupervisionItemQuestion(SupervisionItemQuestionQuery dto) {
        List<SupervisionItemQuestion> list = list(new QueryWrapper<SupervisionItemQuestion>().lambda()
                .eq(Objects.nonNull(dto.getSupervisionItemManagementId()),SupervisionItemQuestion::getSupervisionItemManagementId, dto.getSupervisionItemManagementId())
                .eq(SupervisionItemQuestion::getIsDeleted, BusinessConstant.NO)
                .orderByAsc(SupervisionItemQuestion::getSort));
        return doToVos(list);
    }

    /**
     * do转vo
     *
     * @param model model
     * @return modelVo
     */
    @Override
    public SupervisionItemQuestionVO doToVo(SupervisionItemQuestion model) {
        SupervisionItemQuestionVO modelVo = new SupervisionItemQuestionVO();
        BeanUtils.copyProperties(model, modelVo);
        modelVo.setId(model.getId());
        return modelVo;
    }

    /**
     * do转vo
     *
     * @param modelList modelList
     * @return list
     */
    @Override
    public List<SupervisionItemQuestionVO> doToVos(List<SupervisionItemQuestion> modelList) {
        if (modelList == null || modelList.isEmpty()) {
            return null;
        }
        List<SupervisionItemQuestionVO> result = new ArrayList<>();
        for (SupervisionItemQuestion model : modelList) {
            if(!model.getQuestionType().eq(SupervisionItemQuestionQuestionTypeEnum.ESSAY_QUESTION)){
                model.setMaxWordage(30);
            }
            result.add(doToVo(model));
        }
        return result;
    }
}
